import 'package:xmpp_stone/src/Connection.dart';
import 'package:xmpp_stone/src/data/Jid.dart';
import 'package:xmpp_stone/src/elements/stanzas/AbstractStanza.dart';
import 'package:xmpp_stone/src/elements/stanzas/MessageStanza.dart';
import 'package:xmpp_stone/src/messages/MessageApi.dart';

import '../../xmpp_stone.dart';

class MessageHandler implements MessageApi {
  static Map<Connection, MessageHandler> instances =
      <Connection, MessageHandler>{};

  Stream<MessageStanza> get messagesStream {
    return _connection.inStanzasStream
        .where((abstractStanza) => abstractStanza is MessageStanza)
        .map((stanza) => stanza as MessageStanza);
  }

  static MessageHandler getInstance(Connection connection) {
    var manager = instances[connection];
    if (manager == null) {
      manager = MessageHandler(connection);
      instances[connection] = manager;
    }

    return manager;
  }

  Connection _connection;

  MessageHandler(Connection connection) {
    _connection = connection;
  }

  @override
  void sendMessage(Jid to, String text, MessageType messageType) {
    _sendMessageStanza(to, text, MessageStanzaType.CHAT, messageType);
  }

  @override
  void sendGroupMessage(Jid to, String text, MessageType messageType) {
    _sendMessageStanza(to, text, MessageStanzaType.GROUPCHAT, messageType);
  }

  @override
  void sendHeadline(Jid to, String text, MessageType messageType) {
    _sendMessageStanza(to, text, MessageStanzaType.HEADLINE, messageType);
  }

  @override
  void sendNormal(Jid to, String text,MessageType messageType) {
    _sendMessageStanza(to, text, MessageStanzaType.NORMAL, messageType);
  }

  void _sendMessageStanza(Jid jid, String text,
      MessageStanzaType messageStanzaType, MessageType messageType) {
    var stanza = MessageStanza(AbstractStanza.getRandomId(), messageStanzaType);
    stanza.toJid = jid;
    stanza.fromJid = _connection.fullJid;
    stanza.body = _parseMessageType(messageType, text);
    _connection.writeStanza(stanza);
  }

  XmppElement _parseMessageType(MessageType messageType, String value) {
    var element = XmppElement();
    switch (messageType) {
      case MessageType.TEXT:
        element.name = 'text';
        break;
      case MessageType.IMAGE:
        element.name = 'image';
        break;
      case MessageType.AUDIO:
        element.name = 'audio';
        break;
      case MessageType.VIDEO:
        element.name = 'video';
        break;
      case MessageType.OTHER:
        element.name = 'other';
        break;
    }
    element.textValue = value;
    return element;
  }
}
